import { useEffect, useState, useRef, RefObject } from 'react'
import style from './index.module.less'
import { getDocumentRequest, getSignListRequest, updateSignRequest, getCaseDataRequest, getArbitratorsRequest, getParticipantListRequest, reproductRequest, sendSignRequest, finishSignRequest } from './ajax'
import { $print, awaitWrap, confirmAction } from '@src/assets/js/tool'
import { message, Skeleton, Space, Button } from 'antd'
import { useDispatch } from 'react-redux'
import { addResizeEvent, delResizeEvent } from '@redux/actions/globalEvent'
import { PDFParamSchema, PDFSchema, PDFSignSchema } from '@src/components/schema/pdf'
import moment from 'moment'
import { Document, Page } from 'react-pdf'
import printPng from '@imgs/print.png'
import { download } from '@src/assets/js/downloadRename'
import EditBlock from './components/editBlock'
import { SignContext } from './context'
import { CaseSchema } from '@src/components/schema/caseSchema'
import { ArbitratorSchema } from '@src/components/schema/arbitrator'
import { ParticipantSchema } from '@components/schema/videoCourt'
import SignMove from './components/signMove'
import classNames from 'classnames'

function Loading () {
  return (
    <div className={style['empty-page']}>
      <Skeleton active paragraph={{ rows: 6 }} />
    </div>
  )
}

async function reproduceDoc (fileid: string, refreshFn: () => void) {
  const hide = message.loading('重置文书中', 120)
  const [e] = await awaitWrap(reproductRequest(fileid))
  hide()
  if (e === null) {
    message.success('重置成功')
    refreshFn()
  }
}

async function sendSign (fileid: string, refreshFn: () => void) {
  const hide = message.loading('提交中', 120)
  const [e] = await awaitWrap(sendSignRequest(fileid))
  hide()
  if (e === null) {
    refreshFn()
  }
}

async function initCaseDetail (caseid: string, setCaseDetail: (v: CaseSchema) => void) {
  const [e, d] = await awaitWrap(getCaseDataRequest(caseid))
  if (e === null && d !== null) {
    setCaseDetail(d)
  }
}

async function initArbitratros (caseid: string, setArbitratros: (v: ArbitratorSchema[]) => void) {
  const [e, d] = await awaitWrap(getArbitratorsRequest(caseid))
  if (e === null && d !== null) {
    setArbitratros(d)
  }
}

async function initOtherPersons (caseid: string, setOtherPersons: (v: ParticipantSchema[]) => void) {
  const [e, d] = await awaitWrap(getParticipantListRequest(caseid))
  if (e === null && d !== null) {
    setOtherPersons(d)
  }
}

function setPDFWidth (setWidth: (v: number) => void, setHeight: (v: number) => void, setReady: (v: boolean) => void) {
  // const o = window.document.body.offsetWidth
  // let w = (o > 1420 ? o : 1420) - 622
  let w = 800
  setWidth(w || 0)
  setHeight((w || 0) * 1.4140625)
  setReady(true)
}

// 根据id获取文书
async function getFileById (
  caseid: string,
  fileid: string,
  initState: () => void,
  setFile: (v: PDFSchema) => void,
  setIsSeal: (v: boolean) => void,
  setFormParamsHidden: (v: PDFParamSchema[]) => void,
  setFormParams: (v: PDFParamSchema[]) => void,
  setFormInitData: (v: { [k: string]: any }) => void,
  setFormParamsMap: (v: { [k: string]: PDFParamSchema }) => void,
  setEditable: (v: boolean) => void,
  setIsLocation: (v: boolean) => void,
  setSignStatus: (v: string) => void,
  setDocType: (v: string) => void
) {
  const [e, d] = await awaitWrap(getDocumentRequest(caseid, fileid))
  if (e === null && d !== null) {
    initState()
    if (!d.pdf_path) {
      return setTimeout(() => {
        getFileById(caseid, fileid, initState, setFile, setIsSeal, setFormParamsHidden, setFormParams, setFormInitData, setFormParamsMap, setEditable, setIsLocation, setSignStatus, setDocType)
      }, 2000)
    }
    d.pdf_path = d.pdf_path.replace(/^.*\/upload/, '/upload')
    setDocType(d.type)
    setEditable(d.seal_status === '未发起')
    setSignStatus(d.seal_status)
    setFile(d)
    setIsLocation(d.sign_type === 'location')
    setIsSeal(Boolean(d.seal))
    initFormParamsData(setFormParamsHidden, setFormParams, setFormInitData, setFormParamsMap, d)
  }
}

// 根据文书参数和文书模板参数生成表单参数
function initFormParamsData (
  setFormParamsHidden: (v: PDFParamSchema[]) => void,
  setFormParams: (v: PDFParamSchema[]) => void,
  setFormInitData: (v: { [k: string]: any }) => void,
  setFormParamsMap: (v: { [k: string]: PDFParamSchema }) => void,
  file: PDFSchema
) {
  const formInitData: { [k: string]: any } = {}
  const formParamsMap: { [k: string]: PDFParamSchema } = {}
  const formParamsHidden = (file.parameters || []).filter(li => li.parm_input_type === '隐藏域')
  const formParams = (file.parameters || []).filter(li => li.parm_input_type !== '隐藏域').map(li => {
    const v = li.parm_value
    const t = li.parm_input_type
    const k = li.parm_key
    const td = li.parm_type_data
    if (t === '多选选择器' && v) {
      formInitData[k] = v.split(',').filter(li => li !== '')
    } else if (t === '时间选择器' && v) {
      let filterV = encodeURIComponent(li.parm_value)
      filterV = filterV.replace(/%C2%A0/g, '%20')
      filterV = decodeURIComponent(filterV)
      formInitData[k] = moment(filterV, td || 'YYYY年MM月DD日')
    } else {
      formInitData[k] = v
    }
    formParamsMap[k] = li

    return li
  })
  setFormParamsHidden(formParamsHidden)
  setFormParams(formParams)
  setFormInitData(formInitData)
  setFormParamsMap(formParamsMap)
}

async function initSignList (id: string, setLoading: (v: boolean) => void, setList: (v: PDFSignSchema[]) => void) {
  setLoading(true)
  const [e, d] = await awaitWrap(getSignListRequest(id))
  setLoading(false)
  if (e === null && d !== null) {
    setList(d)
  }
}

async function updateSign (v: { [k: string]: any }, refreshFn: () => void) {
  const h = message.loading('提交中', 120)
  const [e] = await awaitWrap(updateSignRequest(v))
  h()
  if (e === null) {
    refreshFn()
  }
}

function formatPdfPath (file: PDFSchema): string {
  return file.signed_file ? `${file.signed_file.path}` : `${file.pdf_path}`
}

async function finsihSign (id: string, refreshFn: () => void) {
  const h = message.loading('提交中', 120)
  const [e] = await awaitWrap(finishSignRequest(id))
  h()
  if (e === null) {
    refreshFn()
  }
}

interface Props {
  meta: {
    id: string,
    caseid: string
  }
}

function Main ({ meta }: Props) {
  const [caseDetail, setCaseDetail] = useState<CaseSchema | null>(null)
  const [arbitrators, setArbitrators] = useState<ArbitratorSchema[]>([])
  const [otherPersons, setOtherPersons] = useState<ParticipantSchema[]>([])
  const [file, setFile] = useState<PDFSchema | null>(null)
  const [isSeal, setIsSeal] = useState(false)
  const [formParamsHidden, setFormParamsHidden] = useState<PDFParamSchema[]>([])
  const [formParams, setFormParams] = useState<PDFParamSchema[]>([])
  const [formParamsMap, setFormParamsMap] = useState<{[k: string]: PDFParamSchema}>({})
  const [formInitData, setFormInitData] = useState<{[k: string]: any}>({})
  const [width, setWidth] = useState(0)
  const [height, setHeight] = useState(0)
  const [numPages, setNumPages] = useState(0)
  const [ready, setReady] = useState(false)
  const [nums, setNums] = useState<number[]>([])
  const [id, setId] = useState('')
  const [fileid, setFileid] = useState('')
  const [signList, setSignList] = useState<PDFSignSchema[]>([])
  const [signLoading, setSignLoading] = useState(false)
  const [editable, setEditable] = useState(false)
  const [isLocation, setIsLocation] = useState(false)
  const [signStatus, setSignStatus] = useState('')
  const [docType, setDocType] = useState('')
  const dispatch = useDispatch()
  function initData (id: string, fileid: string) {
    getFileById(id, fileid, initState, setFile, setIsSeal, setFormParamsHidden, setFormParams, setFormInitData, setFormParamsMap, setEditable, setIsLocation, setSignStatus, setDocType)
  }
  useEffect(() => {
    if (meta) {
      setId(meta.caseid)
      setFileid(meta.id)
      initCaseDetail(meta.caseid, setCaseDetail)
      initArbitratros(meta.caseid, setArbitrators)
      initOtherPersons(meta.caseid, setOtherPersons)
    }
  }, [meta])

  useEffect(() => {
    const l = []
    for (let i = 0; i < numPages; i++) {
      l.push(i)
    }
    setNums(l)
  }, [numPages])

  useEffect(() => {
    if (id && fileid) {
      initData(id, fileid)
      initSignList(fileid, setSignLoading, setSignList)
    }
  }, [id, fileid])


  function initState () {
    setFile(null)
    setIsSeal(false)
    setFormParamsHidden([])
    setFormParams([])
    setFormParamsMap({})
    setFormInitData({})
  }
  useEffect(() => {
    dispatch(addResizeEvent({ name: `resizePdf-${meta.id}`, handle: () => setPDFWidth(setWidth, setHeight, setReady) }))
    return () => {
      dispatch(delResizeEvent(`resizePdf-${meta.id}`))
    }
  }, [])
  return (
    <SignContext.Provider value={{
      caseDetail,
      arbitrators,
      otherPersons,
      signList,
      signLoading,
      setSignList,
      initSignList: () => initSignList(fileid, setSignLoading, setSignList),
      updateSign: (v) => updateSign(v, () => initSignList(fileid, setSignLoading, setSignList)) }
    }>
      <div className={classNames(style.container, { [style.disabled]: signStatus === '完成' })}>
        <div className={style.left}>
          <div className={style['pdf-operate-line']}>
            <button className={style['pdf-btn']} onClick={() => file ? $print(formatPdfPath(file)) : message.warning('文书不存在')}>
              <img src={printPng} className={style['pdf-btn-icon']} />
              <span>打印</span>
            </button>
            <a className={style['pdf-btn']} onClick={() => { file ? download(formatPdfPath(file), `${file.original_filename}.pdf`) : message.warning('文书不存在') }}>下载pdf</a>
            {/* <a className={style['pdf-btn']} onClick={() => { file ? download(file.docx_path, `${file.original_filename}.docx`) : message.warning('文书不存在') }}>下载docx</a> */}
          </div>
          <div className={style.pdf}>
            {
              isLocation && (
                <SignMove fileid={fileid} ready={ready} width={width} height={height} numPages={numPages} editable={editable} />
              )
            }
            {
              file ? (
                <Document
                  loading={<Loading />}
                  file={formatPdfPath(file)}
                  onLoadSuccess={(e) => {
                    setNumPages(e.numPages)
                    setPDFWidth(setWidth, setHeight, setReady)
                  }}
                  error='文书生成失败，请点击“重新生成”操作。'
                  // options={{ cMapUrl: 'cmaps/', cMapPacked: true }}
                >
                  {
                  ready && (
                    nums.map(i => {
                      return (
                        <div className={style.page} key={i}>
                          <Page pageNumber={i + 1} width={width} height={height} renderTextLayer={false} renderAnnotationLayer={false} />
                        </div>
                      )
                    })
                  )
                  }
                </Document>
              ) : <Loading />
            }
          </div>
        </div>
        <div className={style.split}></div>
        <div className={style['split-step']} />
        <div className={style.right}>
          <EditBlock caseid={id} fileid={fileid} file={file} isLocation={isLocation} editable={editable} formParams={formParams} formInitData={formInitData} isSeal={isSeal} formParamsHidden={formParamsHidden} formParamsMap={formParamsMap} docType={docType} refreshFn={() => {
            initData(id, fileid)
          }} />
        </div>
        {
          signStatus !== '完成' && (
            <div className={style['bottom-line']}>
              <Space size='middle'>
                {
                  editable && (
                    <>
                      {docType !== '用户上传' && <Button onClick={() => confirmAction('本操作会重新抓取最新案件数据，重新生成文书，您确定要执行本操作吗？', () => { reproduceDoc(fileid, () => initData(id, fileid)) })}>重置文书</Button>}
                      <Button type='primary' onClick={() => confirmAction('您确定要发起签署吗？', () => sendSign(fileid, () => { initData(id, fileid) }))}>文书发起签署</Button>
                    </>
                  )
                }
                {
                  signStatus === '签署中' && (
                    <>
                      <Button type='primary' onClick={() => confirmAction('您是否要将文书设置为签署完成？', () => {
                        finsihSign(fileid, () => initData(id, fileid))
                      })}>签署完成</Button>
                    </>
                  )
                }
              </Space>
            </div>
          )
        }
      </div>
    </SignContext.Provider>
  )
}

export default Main
